package ar.com.globallogic.promomr.services;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import ar.com.globallogic.promomr.domain.Publication;
import ar.com.globallogic.promomr.exceptions.PublicationNotFoundException;
import ar.com.globallogic.promomr.persistance.PublicationRepository;

@Service
public class PublicationServiceImpl implements PublicationService{
	
	private static final Logger logger = LoggerFactory.getLogger(PublicationServiceImpl.class);
	
	private PublicationRepository publicationRepository;
		
	@Autowired
	public PublicationServiceImpl(PublicationRepository publicationRepository) {
		super();
		this.publicationRepository = publicationRepository;
	}

	@Override
	public Publication findOne(String id) {
		logger.info(String.format("Finding publication with id %s.", id));
		Publication publication = publicationRepository.findOne(id);
		if(publication == null){
			logger.error(String.format("Publication with id %s was not found.", id));
			throw new PublicationNotFoundException(id);
		}
		logger.info(String.format("Publication with id %s was found.", id));
		return publication;
	}
	
	@Override
	public Publication findByContentId(String contentId) {
		logger.info(String.format("Finding publication with contenId %s.", contentId));
		Publication publication = publicationRepository.findByContentId(contentId);
		if(publication == null){
			logger.error(String.format("Publication with contentId %s was not found.", contentId));
			throw new PublicationNotFoundException(contentId);
		}
		logger.info(String.format("Publication with contentId %s was found.", contentId));
		return publication;
	}

	@Override
	public Publication save(Publication publication) {
		publicationRepository.save(publication);
		logger.info(String.format("Publication with id %s was saved.", publication.getId()));
		return publication;
	}

	@Override
	public Publication publish(Publication publication) {
		publication.publish();
		publicationRepository.save(publication);
		logger.info(String.format("Publication with id %s was published.", publication.getId()));
		return publication;
	}

	@Override
	public Publication publishAt(Publication publication, Date publicationDate) {
		publication.publishAt(publicationDate);
		publicationRepository.save(publication);
		logger.info(String.format("Publication with id %s was set for publishing at %s.", publication.getId(), publicationDate.toString()));
		return publication;
	}

	@Override
	public Publication cancel(Publication publication) {
		publication.cancel();
		publicationRepository.save(publication);
		logger.info(String.format("Publication with id %s was cancelled.", publication.getId()));
		return publication;
	}

	@Override
	@Scheduled(cron="${publication.cron.expression}")
	public void publishPendingPublications() {
		logger.info(String.format("Publishing pending publications."));
		List<Publication> pendingPublications = publicationRepository.findAllPendingPublications();
		for (Publication publication : pendingPublications) {
			publication.publish();
			publicationRepository.save(publication);
			logger.info(String.format("Publication with id %s was published.", publication.getId()));
		}
	}
	
	@Override
	public List<Publication> findPublicationsForContentIdsAndUserId(List<String> contentIds, String userId) {
		logger.info(String.format("Finding publication for contentIds %s and userId %s.", contentIds, userId));
		List<Publication> publications = new ArrayList<Publication>();
		for (String contentId : contentIds) {
			Publication publication = publicationRepository.findByContentIdForUser(contentId, userId);
			if(publication!=null){
				publications.add(publication);
			}
		}		
		return publications;
	}

}
